use nickel::{router::Matcher, HttpRouter, MediaType, Nickel, StaticFilesHandler};

pub fn query_port() -> String {
    let port = std::env::args().nth(2).unwrap_or("8080".to_string());
    format!("localhost:{}", port)
}

pub fn static_server(server: &mut Nickel) {
    if let Some(dir) = std::env::args().nth(1) {
        if !dir.eq("none") && !dir.eq(".") {
            println!("static dir is set at {}", console::style(&dir).red());
            server.utilize(StaticFilesHandler::new(dir));
        } else if dir.eq(".") {
            let dir = std::env::current_dir().unwrap();
            println!(
                "static dir is set at {}",
                console::style(dir.display()).red()
            );
            server.utilize(StaticFilesHandler::new(dir));
        } else {
            println!("static dir is not set");
        }
    } else {
        let dir = std::env::current_dir().unwrap();
        println!(
            "static dir is set at {}",
            console::style(dir.display()).red()
        );
        server.utilize(StaticFilesHandler::new(dir));
    }
}

pub trait RenderFile {
    fn render<M>(&mut self, url: M, content: &'static str, media_type: MediaType)
    where
        M: Into<Matcher>;

    fn render_bytes<M>(&mut self, url: M, content: &'static [u8], media_type: MediaType)
    where
        M: Into<Matcher>;

    fn render_js<M>(&mut self, url: M, content: &'static str)
    where
        M: Into<Matcher>,
    {
        self.render(url.into(), content, MediaType::Js);
    }

    fn render_css<M>(&mut self, url: M, content: &'static str)
    where
        M: Into<Matcher>,
    {
        self.render(url.into(), content, MediaType::Css);
    }

    fn render_html<M>(&mut self, url: M, content: &'static str)
    where
        M: Into<Matcher>,
    {
        self.render(url.into(), content, MediaType::Html);
    }

    fn render_png<M>(&mut self, url: M, content: &'static [u8])
    where
        M: Into<Matcher>,
    {
        self.render_bytes(url.into(), content, MediaType::Png);
    }

    fn render_jpeg<M>(&mut self, url: M, content: &'static [u8])
    where
        M: Into<Matcher>,
    {
        self.render_bytes(url.into(), content, MediaType::Jpeg);
    }
}

impl RenderFile for Nickel {
    fn render<M>(&mut self, url: M, content: &'static str, media_type: MediaType)
    where
        M: Into<Matcher>,
    {
        self.get(
            url.into(),
            middleware! { |_, mut response|
                response.set(media_type);
                content
            },
        );
    }

    fn render_bytes<M>(&mut self, url: M, content: &'static [u8], media_type: MediaType)
    where
        M: Into<Matcher>,
    {
        self.get(
            url.into(),
            middleware! { |_, mut response|
                response.set(media_type);
                content
            },
        );
    }
}
